#include <stdint.h>
#include <stdio.h>
#include <set>
// includes the right splitlock version
#include "pwext.hpp"

class worker;
// [[ex03ka]]
// DEBUG descr The split lock set API separated into the control and worker parts.
// The "external" interface, for the non-control
// threads to see
class splitlock_set_ext
{
public:
	typedef std::set<worker *> worker_set;

	void request_safe();
	void add_thread(worker *w);
	void rm_thread(worker *w);

protected:
	// Protected constructor and destructor: never
	// created nor deleted directly, other than by the
	// subclass
	splitlock_set_ext();
	~splitlock_set_ext();

	worker_set workers_;
	// where the workers are added when the set is
	// locked
	worker_set new_workers_; 
	// signaled on unlocking of the set
	pw::pmcond cond_; 
	// flag: safety of all workers requested, and set
	// has been locked
	bool lset_; 
	// flag: safety of all workers requested
	bool rsafe_; 
};

// The interface used by the control thread
class splitlock_set : public splitlock_set_ext
{
public:
	// the public methods of splitlock_set_ext are
	// inherited as well
	splitlock_set();
	~splitlock_set();
	void wait_safe();
	void lock_safe();
	void release_safe();
	void set_add_unsafe();
	void set_add_safe();
	void lock_set();
	void unlock_set();
	void control_rm_thread(worker *w);
	bool wait_for_workers(const struct timespec 
		&abstime, bool timed = false);
	const worker_set &get_set();

private:
	// cover up the method that must not be used by
	// the control thread
	void rm_thread(worker *w);
};
// END
